<template>
  <div class="abstract-page">
    <!-- 顶部翻页 -->
    <mu-flex v-if="showTopPagin" justify-content="center" class="abstract-page-pagin-box">
      <mu-pagination
        :total="pager.total"
        :current="pager.current_page"
        :page-size="pager.per_page"
        :page-count="isPhone ? 5 : 7"
        @change="changePage"
      ></mu-pagination>
    </mu-flex>
    <!-- 内容 -->
    <div class="abstract-page-content-container">
      <div v-if="outterLoading" class="abstract-page-overlay" :class="{active:innerLoading}">
        <div class="abstract-page-overlay-inner">
          <mu-circular-progress :size="54"></mu-circular-progress>
          <p class="abstract-page-overlay-text mu-primary-text">加载中</p>
        </div>
      </div>
      <slot v-if="isPhone" :source="source" :no-data="noData" name="phone">
        <slot :source="source" :no-data="noData" name="default"></slot>
      </slot>
      <slot v-else :source="source" :no-data="noData" name="pc">
        <slot :source="source" :no-data="noData" name="default"></slot>
      </slot>
    </div>
    <!-- 底部翻页 -->
    <mu-flex v-if="showBottomPagin" justify-content="center" class="abstract-page-pagin-box">
      <mu-pagination
        :total="pager.total"
        :current="pager.current_page"
        :page-size="pager.per_page"
        :page-count="isPhone ? 5 : 7"
        @change="changePage"
      ></mu-pagination>
    </mu-flex>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  name: 'AbstractPage',
  props: {
    fetcher: {
      type: Function,
      required: true
    },
    paginPosition: {
      type: String,
      default: 'follow',
      validator(value) {
        return ['follow', 'top', 'bottom', 'both', 'auto'].indexOf(value) >= 0
      }
    },
    useLoading: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      loading: false,
      pager: {
        current_page: 1,
        last_page: 0,
        per_page: 15,
        total: 0
      },
      source: [],
      outterLoading: false,
      innerLoading: false
    }
  },
  computed: {
    ...mapGetters({
      isPhone: 'isPhone',
      types: 'types',
      pagin: 'pagin'
    }),
    noData() {
      return this.source.length <= 0
    },
    showTopPagin() {
      const pagin = (this.paginPosition === 'follow') ? (this.pagin) : (this.paginPosition)
      return (['top', 'both'].indexOf(pagin) >= 0) || (pagin === 'auto' && this.isPhone)
    },
    showBottomPagin() {
      const pagin = (this.paginPosition === 'follow') ? (this.pagin) : (this.paginPosition)
      return (['bottom', 'both'].indexOf(pagin) >= 0) || (pagin === 'auto')
    },
    compLoading() {
      return this.useLoading ? this.loading : false
    }
  },
  watch: {
    compLoading(val) {
      if (val) {
        this.outterLoading = true
        setTimeout(() => {
          this.innerLoading = true
        }, 0)
      } else {
        this.innerLoading = false
        setTimeout(() => {
          this.outterLoading = false
        }, 600)
      }
    }
  },
  created() {
    this.changePage(1)
  },
  methods: {
    // 切换到第x页
    async changePage(page) {
      this.loading = true
      try {
        const data = await this.fetcher(page)
        if (data !== null) {
          this.source = data.data
          this.pager.last_page = parseInt(data.last_page)
          this.pager.per_page = parseInt(data.per_page)
          this.pager.total = parseInt(data.total)
          this.pager.current_page = Math.max(1, Math.min(parseInt(data.last_page), parseInt(page)))
        }
      } catch (err) {
        this.$apiCatch(err)
      }
      this.loading = false
    },
    // 刷新
    refresh() {
      this.changePage(this.pager.current_page)
    }
  }
}
</script>

<style>
.abstract-page-pagin-box {
  margin: 10px 0;
}
.abstract-page-content-container {
  position: relative;
}
.abstract-page-overlay {
  position: absolute;
  display: flex;
  flex-flow: column nowrap;
  justify-content: center;
  align-items: center;
  background-color: #fff0;
  width: 100%;
  height: 100%;
  transition: background-color 0.6s;
}
.abstract-page-overlay-inner {
  opacity: 0;
  transition: opacity 0.6s;
}
.abstract-page-overlay.active {
  background-color: #fff6;
}
.abstract-page-overlay.active .abstract-page-overlay-inner {
  opacity: 1;
}
.abstract-page-overlay-text {
  margin-top: 6px;
  font-size: 20px;
}
</style>
